from sbs_server import GameServer
from game_storage import GameStorage
from game_shared import STOCHASTIC_VALUE, PASSWORD
from game_shared import SHARED_SERVER_PORT
import random

#=======================================================================================================================
# MyBattleshipsServer
#=======================================================================================================================
class MyBattleshipsServer(GameServer):
    def __init__(self):
        GameServer.__init__(self)
        
        self.game_storage = GameStorage()
                
        #------- For the Client ----------------------------------
        self.register_message_handler('enter_game', self.on_enter_game)
        self.register_message_handler('place_boat', self.on_place_boat)
        self.register_message_handler('shoot', self.on_shoot)
        self.register_message_handler('get_state', self.on_get_state)
        self.register_message_handler('did_i_win', self.on_did_i_win)
        self.register_message_handler('win_loss_count', self.on_win_loss_count)
        self.register_message_handler('get_opponents_last_game_shots', self.on_get_opponents_last_game_shots)
        self.register_message_handler('get_opponents_last_game_placement', self.on_get_opponents_last_game_placement)
        self.register_message_handler('get_avg_shots_taken', self.on_get_avg_shots_taken)
        
        #------- For the Manager ----------------------------------
        self.register_message_handler('add_game', self.on_add_game)
        self.register_message_handler('snapshot', self.on_snapshot)
       
    def on_execute(self):
        pass
          
    def on_add_game(self, addr, game_id, password):
        ''' ONLY TO BE USED BY THE GAME MANAGER'''
        game_id = game_id.lower()
        
        try:
            if password != PASSWORD: raise
            
            self.game_storage.add_game(game_id)
            return True 
                
        except:
            print "Error while adding GAME: {1}".format( game_id )
            return "error"
    
    def on_snapshot(self, addr, game_id):
        try:
            # Make sure this game_id has been placed in storage by the "manager"
            if game_id in self.game_storage.games:
                self.game_storage.snapshot(game_id)
            return True
                
        except:
            print "Error"
            return "error"
              
    def on_enter_game(self, addr, game_id, player_id):
        try:
            # Make sure this game_id has been placed in storage by the "manager"
            if game_id in self.game_storage.games:
                self.game_storage.set_player_for_game(game_id, player_id) 
            return True
                
        except:
            raise
            print "Error while PLAYER: {0} was trying to enter GAME: {1}".format( player_id, game_id )
            return "error"
    
    def on_place_boat(self, addr, game_id, player_id, length, x_coord, y_coord, orientation):
        try:
            if game_id in self.game_storage.games:
                self.game_storage.place_boat_for_player(game_id, player_id, length, x_coord, y_coord, orientation)
                return True
        except:
            print "Error while PLAYER: {0} was trying to place boat for GAME: {1}".format( player_id, game_id )
            return "Error"

    def on_shoot(self, addr, game_id, player_id, x_coord, y_coord):
        hit = False
        #self.game_storage.snapshot(game_id)
        
        try:
            if game_id in self.game_storage.games:
                hit = self.game_storage.shoot( game_id, player_id, x_coord, y_coord )
                
                if hit == "stop":
                    return (187, 0) #Code for when someone dies : )
                
                if hit == "fail":
                    return (187, 1)
                
                #-------|| THE STOCHASTIC MAGIC ||--------
                elif hit and random.random() > STOCHASTIC_VALUE:
                    return (True, 0)
                
                else:
                    return (False, 0)         
                    
        except:
            raise
            print "Error while PLAYER: {0} was trying to shoot for GAME: {1}".format( player_id, game_id )
            return "Error"
                
    def on_get_state(self, addr, game_id):
        try:
            if game_id in self.game_storage.games:
                return self.game_storage.get_state_for_game( game_id )
                
     
        except:
            print "Error while getting state for GAME: {0}".format( game_id )
            return "Error"
       
    def on_did_i_win(self, addr, game_id, player_id):
        try:
            if game_id in self.game_storage.games:
                return self.game_storage.did_i_win( game_id, player_id )
                
        except:
            return "error"
    
    def on_win_loss_count(self, addr, game_id, player_id):
        try:
            if game_id in self.game_storage.games:
                return self.game_storage.win_loss_count( game_id, player_id )
        except:
            return "error"

    def on_get_opponents_last_game_shots(self, addr, game_id, player_id):
        try:
            if game_id in self.game_storage.games:
                return self.game_storage.get_opponents_last_game_shots( game_id, player_id )
        except:
            raise
            return "error"

    def on_get_opponents_last_game_placement(self, addr, game_id, player_id):
        try:
            if game_id in self.game_storage.games:
                return self.game_storage.get_opponents_last_game_placement( game_id, player_id )
        except:
            raise
            return "error" 
    
    def on_get_avg_shots_taken(self, addr, game_id, player_id):
        try:
            if game_id in self.game_storage.games:
                return self.game_storage.get_avg_shots_taken( game_id, player_id )
        except:
            raise
            return "error"
         
        
     
#=======================================================================================================================
# STARTS THE SERVER.
#=======================================================================================================================
s = MyBattleshipsServer()
# host, port
s.start('localhost', SHARED_SERVER_PORT)

print '\n-------'
print "[For testing purposes] Sample game added with game_id: redsea & northsea"
s.on_add_game( s.port, 'redsea',  'stochastic' )
s.on_add_game( s.port, 'northsea',  'stochastic' )
print '-------\n'

while 1:
    s.execute()
